#include "stdafx.h"
#include <assert.h>
#include "UIDrawTool.h"
#pragma comment(lib,"Msimg32.lib")
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CUIDrawTool::CUIDrawTool()
{

}

CUIDrawTool::~CUIDrawTool()
{

}

BOOL CUIDrawTool::FillSolidRect( HDC hDC, const RECT& rect, COLORREF clr )
{
    COLORREF clrOld = ::SetBkColor( hDC, clr );
    ::ExtTextOut( hDC, 0, 0, ETO_OPAQUE, &rect, NULL, 0, NULL );
    ::SetBkColor( hDC, clrOld );
    return TRUE;
}

BOOL CUIDrawTool::FillSolidRect( HDC hDC, const RECT& rect, HBRUSH hBrush )
{
    ::FillRect( hDC, &rect, hBrush );
    return TRUE;
}

void CUIDrawTool::SetRoundRect( HWND hWnd, int ix, int iy )
{
    RECT rect = {0};
    ::GetWindowRect( hWnd, &rect );
    ::OffsetRect( &rect, -rect.left, -rect.top );
    HRGN hRgn =::CreateRoundRectRgn( rect.left, rect.top, rect.right, rect.bottom, ix, iy );
    ::SetWindowRgn( hWnd, hRgn, TRUE );
    ::DeleteObject( hRgn );
}

/** 用指定的画刷填充矩形
 * @param hdc
 * @param x
 * @param y
 * @param cx
 * @param cy
 * @param hBrush
*/
BOOL CUIDrawTool::FillSolidRect( HDC hdc, int x, int y, int cx, int cy, HBRUSH hBrush )
{
    RECT rc;
    ::SetRect( &rc, x, y, x + cx, y + cy );
    return FillSolidRect( hdc, rc, hBrush );
}

/** 用指定的颜色填充矩形
 * @param hdc
 * @param x
 * @param y
 * @param cx
 * @param cy
 * @param clr
*/
BOOL CUIDrawTool::FillSolidRect( HDC hdc, int x, int y, int cx, int cy, COLORREF clr )
{
    RECT rc;
    ::SetRect( &rc, x, y, x + cx, y + cy );
    return FillSolidRect( hdc, rc, clr );
}

/** 用指定的画笔绘制圆角矩形
 * @param hdc
 * @param x
 * @param y
 * @param cx
 * @param cy
 * @param hPen
*/
void CUIDrawTool::DrawRoundRect( HDC hdc, int x, int y, int cx, int cy, int x1, int y1, HPEN hPen )
{
    HPEN hOldPen = ( HPEN )::SelectObject( hdc, hPen );
    ::RoundRect( hdc, x, y, x + cx, y + cy, x1, y1 );
    ::SelectObject( hdc, hOldPen );
    ::DeleteObject( hOldPen );
}

/** 用指定的颜色绘制空心矩形
 * @param hdc
 * @param lprc
 * @param nSize
 * @param clr
*/
void CUIDrawTool::DrawFrame( HDC hdc, LPRECT lprc, int nSize, COLORREF clr )
{
    FillSolidRect( hdc, lprc->left, lprc->top, lprc->right - nSize, nSize, clr );
    FillSolidRect( hdc, lprc->left, lprc->top, nSize, lprc->bottom  - nSize, clr );
    FillSolidRect( hdc, lprc->left + lprc->right, lprc->top, -nSize, lprc->bottom - nSize, clr );
    FillSolidRect( hdc, lprc->left, lprc->top + lprc->bottom, lprc->right, -nSize, clr );
}

/** 用指定的画笔绘制空心矩形
 * @param hdc
 * @param lprc
 * @param nSize
 * @param hBrush
*/
void CUIDrawTool::DrawFrame( HDC hdc, LPRECT lprc, int nSize, HBRUSH hBrush )
{
    FillSolidRect( hdc, lprc->left, lprc->top, lprc->right - nSize, nSize, hBrush );
    FillSolidRect( hdc, lprc->left, lprc->top, nSize, lprc->bottom - nSize, hBrush );
    FillSolidRect( hdc, lprc->left + lprc->right - nSize, lprc->top, nSize, lprc->bottom, hBrush );
    FillSolidRect( hdc, lprc->left, lprc->top + lprc->bottom - nSize, lprc->right - nSize, nSize, hBrush );
}

/** 屏幕坐标转换为非客户区坐标
*/
void CUIDrawTool::ScreenToFrame( HWND hWnd, POINT& pt )
{
    RECT rcWnd;
    ::GetWindowRect( hWnd, &rcWnd );
    pt.y -= rcWnd.top;

    if ( GetWindowLong( hWnd, GWL_EXSTYLE ) & WS_EX_LAYOUTRTL )
    {
        pt.x = rcWnd.right - pt.x;
    }
    else
    {
        pt.x -= rcWnd.left;
    }
}

void CUIDrawTool::GradientFillSlow( HDC hDC, RECT& Rect, COLORREF crFrom, COLORREF crTo, BOOL bHorz )
{
    int ix = max( 1, Rect.right - Rect.left );
    int iy = max( 1, Rect.bottom - Rect.top );

    RECT rcDest = {0};
    ::GetClipBox( hDC, &rcDest );

    if ( ::IsRectEmpty( &rcDest ) )
    {
        ::CopyRect( &rcDest, &Rect );
    }
    else
        ::IntersectRect( &rcDest, &rcDest, &Rect );

    if ( bHorz )
    {
        for ( int i = rcDest.left; i < rcDest.right; i++ )
        {
            FillSolidRect( hDC, i, rcDest.top, 1, rcDest.bottom - rcDest.top, BlendColors(
                               crFrom, crTo, ( double )( 1.0 - ( ( i - Rect.left ) / ( double )ix ) ) ) );
        }
    }
    else
    {
        for ( int i = rcDest.top; i < rcDest.bottom; i++ )
        {
            FillSolidRect( hDC, rcDest.left, i, rcDest.right - rcDest.left, 1, BlendColors(
                               crFrom, crTo, ( double )( 1.0 - ( ( i - Rect.top ) ) / ( double )iy ) ) );
        }
    }
}

void CUIDrawTool::GradientFillFast( HDC hDC, RECT& Rect, COLORREF crFrom, COLORREF crTo, BOOL bHorz )
{
    TRIVERTEX vert[2];
    vert[0].x = Rect.left;
    vert[0].y = Rect.top;
    vert[0].Red = ( COLOR16 )( GetRValue( crFrom ) << 8 );
    vert[0].Green = ( COLOR16 )( GetGValue( crFrom ) << 8 );
    vert[0].Blue = ( COLOR16 )( GetBValue( crFrom ) << 8 );
    vert[0].Alpha = 0x0000;

    vert[1].x = Rect.right;
    vert[1].y = Rect.bottom;
    vert[1].Red = ( COLOR16 )( GetRValue( crTo ) << 8 );
    vert[1].Green = ( COLOR16 )( GetGValue( crTo ) << 8 );
    vert[1].Blue = ( COLOR16 )( GetBValue( crTo ) << 8 );
    vert[1].Alpha = 0x0000;

    GRADIENT_RECT gRect = { 0, 1 };

    GradientFill( hDC, vert, 2, &gRect, 1, bHorz ? GRADIENT_FILL_RECT_H : GRADIENT_FILL_RECT_V );
}

COLORREF CUIDrawTool::BlendColors( COLORREF crA, COLORREF crB, double fAmountA )
{
    double fAmountB = ( 1.0 - fAmountA );
    int btR = ( int )( GetRValue( crA ) * fAmountA + GetRValue( crB ) * fAmountB );
    int btG = ( int )( GetGValue( crA ) * fAmountA + GetGValue( crB ) * fAmountB );
    int btB = ( int )( GetBValue( crA ) * fAmountA + GetBValue( crB ) * fAmountB );

    return RGB( min( 255, btR ), ( BYTE )min( 255, btG ), ( BYTE )min( 255, btB ) );
}

/** 拷贝窗口背景色到前景色(透明)
*/
void CUIDrawTool::CopyBackground2Foreground( HWND hWnd )
{
    assert( NULL !=::GetParent( hWnd ) );

    HWND hParent =::GetParent( hWnd );
    RECT rcParent = {0};
    RECT rcControl = {0};
    POINT pt = {0};

    ::GetWindowRect( hWnd, &rcControl );
    ::GetWindowRect( hParent, &rcParent );
    pt.x = rcControl.left - rcParent.left;
    pt.y = rcControl.top - rcParent.top;
//	::ScreenToClient(hParent,&pt);


    HDC hParentDC =::GetWindowDC( hParent );
    HDC hControlDC =::GetDC( hWnd );
    ::BitBlt( hControlDC, 0, 0, rcControl.right - rcControl.left, rcControl.bottom - rcControl.top, hParentDC, pt.x, pt.y, SRCCOPY );
    ::ReleaseDC( hParent, hParentDC );
    ::ReleaseDC( hWnd, hControlDC );

}

void CUIDrawTool::InvalidataSelf( HWND hWnd )
{
    RECT rcClient = {0};
    ::GetClientRect( hWnd, &rcClient );
    InvalidateRect( hWnd, &rcClient, TRUE );
}

void CUIDrawTool::InvalidataParent( HWND hWnd )
{
    HWND hParent =::GetParent( hWnd );
    RECT rcWnd = {0};
    ::GetWindowRect( hWnd, &rcWnd );
    POINT pt = {0};
    pt.x = rcWnd.left;
    pt.y = rcWnd.top;
    ::ScreenToClient( hParent, &pt );
    RECT rcClip = {0};
    rcClip.left = pt.x;
    rcClip.top = pt.y;
    rcClip.right = rcClip.left + rcWnd.right - rcWnd.left;
    rcClip.bottom = rcClip.top + rcWnd.bottom - rcWnd.top;
    InvalidateRect( hParent, &rcClip, TRUE );
}